//--------------------------------------
// HexCalc.cs  2001 by Charles Petzold
//--------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
class HexCalc: Form
{
	Button btnResult;
	ulong ulNum = 0;
	ulong ulFirstNum = 0;
	bool bNewNumber = true;
	char chOperation = '=';
	public static void Main()
	{
		Application.Run(new HexCalc());
	}
	public HexCalc()
	{
		Text = "Hex Calc";
//		Icon = new Icon(GetType(), "HexCalc.HexCalc.ico");
		FormBorderStyle = FormBorderStyle.FixedSingle;
		MaximizeBox = false;
		new CalcButton(this, "D", 'D', 8, 24, 14, 14);
		new CalcButton(this, "A", 'A', 8, 40, 14, 14);
		new CalcButton(this, "7", '7', 8, 56, 14, 14);
		new CalcButton(this, "4", '4', 8, 72, 14, 14);
		new CalcButton(this, "1", '1', 8, 88, 14, 14);
		new CalcButton(this, "0", '0', 8, 104, 14, 14);
		new CalcButton(this, "E", 'E', 26, 24, 14, 14);
		new CalcButton(this, "B", 'B', 26, 40, 14, 14);
		new CalcButton(this, "8", '8', 26, 56, 14, 14);
		new CalcButton(this, "5", '5', 26, 72, 14, 14);
		new CalcButton(this, "2", '2', 26, 88, 14, 14);
		new CalcButton(this, "Back", '\x08', 26, 104, 32, 14);
		new CalcButton(this, "C", 'C', 44, 40, 14, 14);
		new CalcButton(this, "F", 'F', 44, 24, 14, 14);
		new CalcButton(this, "9", '9', 44, 56, 14, 14);
		new CalcButton(this, "6", '6', 44, 72, 14, 14);
		new CalcButton(this, "3", '3', 44, 88, 14, 14);
		new CalcButton(this, "+", '+', 62, 24, 14, 14);
		new CalcButton(this, "-", '-', 62, 40, 14, 14);
		new CalcButton(this, "*", '*', 62, 56, 14, 14);
		new CalcButton(this, "/", '/', 62, 72, 14, 14);
		new CalcButton(this, "%", '%', 62, 88, 14, 14);
		new CalcButton(this, "Equals", '=', 62, 104, 32, 14);
		new CalcButton(this, "&&", '&', 80, 24, 14, 14);
		new CalcButton(this, "|", '|', 80, 40, 14, 14);
		new CalcButton(this, "^", '^', 80, 56, 14, 14);
		new CalcButton(this, "<", '<', 80, 72, 14, 14);
		new CalcButton(this, ">", '>', 80, 88, 14, 14);
		btnResult =
			new CalcButton(this, "0", '\x1B', 8, 4, 86, 14);
		foreach (Button btn in Controls)
			btn.Click += new EventHandler(ButtonOnClick);
		ClientSize = new Size(102, 126);
		Scale(Font.Height / 8f);
	}
	protected override void OnKeyPress(KeyPressEventArgs kpea)
	{
		char chKey = Char.ToUpper(kpea.KeyChar);
		if (chKey == '\x0D')
							   chKey = '=';
		for (int i = 0; i < Controls.Count; i++)
		{
			CalcButton btn = (CalcButton) Controls[i];
			if (chKey == btn.chKey)
			{
				InvokeOnClick(btn, EventArgs.Empty);
				break;
			}
		}
	}
	void ButtonOnClick(object obj, EventArgs ea)
	{
		CalcButton btn = (CalcButton) obj;
		if (btn.chKey == '\x08')
								   ulNum /= 16;
		else if (btn.chKey == '\x1B')
										ulNum = 0;
		else if (Char.IsLetterOrDigit(btn.chKey)) // Hex digit
			 {
				 if (bNewNumber)
				 {
					 ulFirstNum = ulNum;
					 ulNum = 0;
					 bNewNumber = false;
				 }
				 if (ulNum <= ulong.MaxValue >> 4)
					 ulNum = 16 * ulNum +
						 (ulong)(btn.chKey -
						 (Char.IsDigit(btn.chKey) ? '0' : 'A' - 10));
			 }
		else // Operation
		{
			if(!bNewNumber)
			{
				switch(chOperation)
					 {
						 case '=': ulNum = ulNum; break;
						 case '+': ulNum = ulFirstNum + ulNum; break;
						 case '-': ulNum = ulFirstNum - ulNum; break;
						 case '*': ulNum = ulFirstNum * ulNum; break;
						 case '&': ulNum = ulFirstNum & ulNum; break;
						 case '|': ulNum = ulFirstNum | ulNum; break;
						 case '^': ulNum = ulFirstNum ^ ulNum; break;
						 case '<': ulNum = ulFirstNum << (int)ulNum; break;
						 case '>': ulNum = ulFirstNum >> (int)ulNum; break;
						 case '/': ulNum = ulNum != 0 ?  ulFirstNum / ulNum :
									   ulong.MaxValue;
							 break;
						 case '%': ulNum = ulNum != 0 ?
									   ulFirstNum % ulNum :
									   ulong.MaxValue;
							 break;
						 default: ulNum = 0; break;
					 }
			}
				 bNewNumber = true;
				 chOperation = btn.chKey;
		}
		btnResult.Text = String.Format("{0:X}", ulNum);
	}
}
class CalcButton: Button
{
	public char chKey;
	public CalcButton(Control parent, string str, char chkey,
		int x, int y, int cx, int cy)
	{
		Parent = parent;
		Text = str;
		chKey = chkey;
		Location = new Point(x, y);
		Size = new Size(cx, cy);
		SetStyle(ControlStyles.Selectable, false);
	}
}